(function () {

  var columnNames = ['A', 'B', 'C', 'D', 'E', 'F'];
  var table = document.getElementById('formulaTable');
  var tbody = table.getElementsByTagName('tbody')[0];
  var info = document.getElementById('info');

  function c(tagName) {
    return document.createElement(tagName);
  }

  function message(msg) {
    info.innerHTML = msg;
  }

  function randomNum(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
  }

  function cNumTd(num) {
    var td = c('td');
    td.innerHTML = num;
    return td;
  }

  function cRandomTd() {
    var td = c('td');
    var input = c('input');
    input.value = randomNum(0, 99999);
    input.placeholder = 'NULL';
    processNormalInput(input);
    td.appendChild(input);
    return td;
  }

  function cFormulaTd() {
    var td = c('td');
    var input = c('input');
    td.style.paddingTop = '20px';
    input.placeholder = 'NULL';
    processFormulaInput(input);
    td.appendChild(input);
    return td;
  }

  function getCellMap() {
    var result = {};
    var children = tbody.children;
    for (var i = 0, j = children.length - 1; i < j; i++) {
      var num = i + 1;
      var columns = children[i].children;
      for (var k = 1, l = columns.length; k < l; k++) {
        result[columnNames[k - 1] + num] = columns[k].children[0].value;
      }
    }
    return result;
  }

  function processNormalInput(input) {
    input.onblur = function () {
      var rows = tbody.children;
      var row = rows[rows.length - 1];
      var columns = row.children;
      for (var i = 1, j = columns.length; i < j; i++) {
        var input = columns[i].children[0];
        if (input.formula) {
          input.value = input.formula;
        }
        executeFormula(input);
      }
    }
  }

  function processFormulaInput(input) {
    input.onfocus = function () {
      var formula = input.formula;
      if (formula) {
        input.value = formula;
      }
    };
    input.onblur = function () {
      executeFormula(input);
    }
  }

  function executeFormula(input) {
    var formula = input.value;
    if (/^[\s]*$/.test(formula)) {
      message('Empty');
      return;
    }
    var cellMap = getCellMap();
    message('Executing......');
    $.ajax({
      url: '/formula/execute',
      type: 'POST',
      dataType: 'json',
      processData: false,
      contentType: 'application/json;charset=UTF-8',
      data: JSON.stringify({formula: formula, cellMap: cellMap}),
      success: function (data) {
        if (data.success) {
          if (input !== document.activeElement) {
            input.value = data.result;
            input.formula = formula;
          }
          message('Success');
        } else {
          message(data['errorMsg']);
        }
      },
      error: function () {
        message('Server connected error')
      }
    })
  }

  function cRandomTr(num, columns) {
    var tr = c('tr');
    tr.appendChild(cNumTd(num));
    for (var i = 0; i < columns; i++) {
      tr.appendChild(cRandomTd())
    }
    return tr;
  }

  function genFormulaTr(columns) {
    var tr = c('tr');
    tr.appendChild(cNumTd(''));
    for (var i = 0; i < columns; i++) {
      tr.appendChild(cFormulaTd())
    }
    return tr;
  }

  function genTr(count) {
    var num = tbody.children.length + 1;
    var columns = 6;
    for (var i = 0; i < count; i++) {
      tbody.appendChild(cRandomTr(num++, columns));
    }
    tbody.appendChild(genFormulaTr(columns));
  }

  function init() {
    genTr(5);
  }

  init();

})();